/*
 * @Author: your name
 * @Date: 2021-04-09 10:37:09
 * @LastEditTime: 2021-04-09 11:07:22
 * @LastEditors: your name
 * @Description: In User Settings Edit
 * @FilePath: /vite-project/src/utils/Storage.ts
 */
/*
 * @Author: your name
 * @Date: 2021-04-09 10:37:09
 * @LastEditTime: 2021-04-09 11:06:15
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: /vite-project/src/utils/Storage.ts
 */
// 默认缓存期限为7天
const DEFAULT_CACHE_TIME = 60 * 60 * 24 * 7;

/**
 * @description: 创建本地缓存对象
 * @param {*} param1
 * @return {*}
 */
export const createStorage = ({
    prefixKey = '',
    storage = localStorage,
} = {}) => {
    /**
     * @description: 本地缓存类
     * @param {*}
     * @return {*}
     */
    const Storage = class {
        private storage = storage;
        private prefixKey?: string = prefixKey;

        /**
         * @description: 设置存储的key
         * @param {string} key
         * @return {*}
         */
        private getKey(key: string) {
            return `${this.prefixKey}${key}`.toUpperCase();
        }

        /**
         * @description: 设置缓存
         * @param {string} key
         * @param {any} value
         * @param {number} expire 存储期限
         * @return {*}
         */
        set(
            key: string,
            value: any,
            expire: number | null = DEFAULT_CACHE_TIME
        ) {
            const stringData = JSON.stringify({
                value,
                expire:
                    expire !== null
                        ? new Date().getTime() + expire * 1000
                        : null,
            });
            this.storage.setItem(this.getKey(key), stringData);
        }

        /**
         * @description: 读取缓存
         * @param {string} key
         * @param {any} def
         * @return {*}
         */
        get(key: string, def: any = null) {
            // 获取缓存内容
            const item = this.storage.getItem(this.getKey(key));
            if (item) {
                try {
                    //将json串转换为json对象
                    const data = JSON.parse(item);
                    const { value, expire } = data;
                    //在有效期内直接返回
                    if (expire === null || expire >= Date.now()) {
                        return value;
                    } else {
                        this.remove(this.getKey(key));
                    }
                } catch (e) {
                    return def;
                }
            }
            return def;
        }

        /**
         * @description: 从缓存中删除某项
         * @param {string} key
         * @return {*}
         */
        remove(key: string) {
            this.storage.removeItem(this.getKey(key));
        }

        /**
         * @description: 清除缓存
         * @param {*}
         * @return {*}
         */
        clear(): void {
            this.storage.clear();
        }

        /**
         * @description: 设置cookie
         * @param {string} name
         * @param {any} value cookie值
         * @param {number} expire 过期时间 如果过期时间未设置，默认关闭浏览器自动删除
         * @return {*}
         */
        setCookie(
            name: string,
            value: any,
            expire: number | null = DEFAULT_CACHE_TIME
        ) {
            document.cookie = `${this.getKey(
                name
            )}=${value}; Max-Age=${expire}`;
        }

        /**
         * @description: 根据名字获取cookie值
         * @param {string} name
         * @return {*}
         */
        getCookie(name: string): string {
            const cookieArr = document.cookie.split(';');
            for (let i = 0, length = cookieArr.length; i < length; i++) {
                const kv = cookieArr[i].split('=');
                if (kv[0] === this.getKey(name)) {
                    return kv[1];
                }
            }
            return '';
        }

        /**
         * @description: 根据名字删除指定的cookie
         * @param {string} key
         * @return {*}
         */
        removeCookie(key: string) {
            this.setCookie(key, 1, -1);
        }

        /**
         * @description: 清空cookie,使所有的cookie失效
         * @param {*}
         * @return {*}
         */
        clearCookie(): void {
            const keys = document.cookie.match(/[^ =;]+(?==)/g);
            if (keys) {
                for (let i = keys.length; i--; ) {
                    document.cookie =
                        keys[i] + '=0;expire=' + new Date(0).toUTCString();
                }
            }
        }
    };
    return new Storage();
};

export const storage = createStorage();

export default Storage;
